﻿namespace Leetcode.N0037;
public class Solution
{
    char[] lettes = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    public void SolveSudoku(char[][] board)
    {
        this.Fill(board, 0, 0);
    }

    private bool Fill(char[][] board, int row, int col)
    {
        if (row == 9)
        {
            return true;
        }

        int nextRow = row;
        int nextCol = col;
        if (col == 8)
        {
            nextRow++;
            nextCol = 0;
        }
        else
        {
            nextCol++;
        }

        if (board[row][col] == '.')
        {
            for (var i = 0; i < 9; i++)
            {
                if (this.Check(board, row, col, lettes[i]))
                {
                    board[row][col] = lettes[i];
                    if (this.Fill(board, nextRow, nextCol))
                    {
                        return true;
                    }
                }
            }
            board[row][col] = '.';
            return false;
        }
        else
        {
            return this.Fill(board, nextRow, nextCol);
        }
    }

    private bool Check(char[][] board, int row, int col, char value)
    {
        if (!this.CheckRow(board, row, value))
        {
            return false;
        }

        if (!this.CheckCol(board, col, value))
        {
            return false;
        }

        if (!this.CheckBlock(board, row, col, value))
        {
            return false;
        }
        return true;
    }
    private bool CheckRow(char[][] board, int row, char value)
    {
        for (var i = 0; i < 9; i++)
        {
            if (board[row][i] == value)
            {
                return false;
            }
        }
        return true;
    }

    private bool CheckCol(char[][] board, int col, char value)
    {
        for (var i = 0; i < 9; i++)
        {
            if (board[i][col] == value)
            {
                return false;
            }
        }
        return true;
    }

    private bool CheckBlock(char[][] board, int row, int col, char value)
    {
        int rm = row / 3;
        int cm = col / 3;

        for (var r = 0; r < 3; r++)
        {
            for (var c = 0; c < 3; c++)
            {
                if (board[rm * 3 + r][cm * 3 + c] == value)
                {
                    return false;
                }
            }
        }
        return true;
    }
}
